﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using YArchitech.Revit;

namespace YArchitech.Temp
{
	internal static class YJKElementNodeExtern
	{
		public static bool GetSideConnector(this ElementNode en, out Connector side1, out Connector side2)
		{
			side1 = null;
			side2 = null;
			if (en.SubConnectors == null)
			{
				return false;
			}
			IEnumerable<Connector> enumerable = from conn in en.SubConnectors
			orderby conn.Flow descending
			select conn;
			int num = 0;
			IEnumerator<Connector> enumerator = enumerable.GetEnumerator();
			while (enumerator.MoveNext() && num < 3)
			{
				num++;
				if (1 == num)
				{
					side1 = enumerator.Current;
				}
				else if (2 == num)
				{
					side2 = enumerator.Current;
				}
			}
			return true;
		}

		public static void DumpIntoXML(this ElementNode en, XElement xeParent)
		{
			FamilyInstance familyInstance = en.Element as FamilyInstance;
			XElement xelement = new XElement("MEPObject");
			xeParent.Add(xelement);
			xelement.SetAttributeValue("Id", en.Element.Id.IntegerValue);
			xelement.SetAttributeValue("Name", en.Element.Name);
			if (familyInstance != null)
			{
				MEPModel mepmodel = familyInstance.MEPModel;
				string value = string.Empty;
				if (mepmodel is MechanicalEquipment)
				{
					value = "MechanicalEquipment";
					xelement.SetAttributeValue("Type", value);
				}
				else if (mepmodel is MechanicalFitting)
				{
					MechanicalFitting mechanicalFitting = mepmodel as MechanicalFitting;
					value = "MechanicalFitting";
					xelement.SetAttributeValue("Type", value);
					xelement.SetAttributeValue("Category", en.Element.Category.Name);
					xelement.SetAttributeValue("PartType", mechanicalFitting.PartType.ToString());
				}
				else
				{
					value = "FamilyInstance";
					xelement.SetAttributeValue("Type", value);
					xelement.SetAttributeValue("Category", en.Element.Category.Name);
				}
			}
			else
			{
				string name = en.Element.GetType().Name;
				xelement.SetAttributeValue("Type", name);
			}
			if (en.Next == null)
			{
				xelement.SetAttributeValue("Next", "NULL");
			}
			else
			{
				en.Next.DumpIntoXML(xeParent);
			}
			if (en.SubElementNode == null)
			{
				return;
			}
			foreach (ElementNode en2 in en.SubElementNode)
			{
				XElement xelement2 = new XElement("Path");
				xelement.Add(xelement2);
				en2.DumpIntoXML(xelement2);
			}
		}

		public static HYMEPObject CreateObject(this ElementNode en, ref HYDuctSystem system)
		{
			if (en.Element == null)
			{
				return null;
			}
			HYMEPObject hymepobject = RevitDataExchange.CreateMEPObject(en.Element);
			if (hymepobject == null)
			{
				return null;
			}
			system.Add(hymepobject);
			ElementNode next = en.Next;
			if (next != null)
			{
				hymepobject.AddNext(next, ref system);
			}
			if (hymepobject is HYAccessory)
			{
				if (en.SubElementNode != null)
				{
					hymepobject.AddNext(en.SubElementNode.First<ElementNode>(), ref system);
				}
			}
			else if (en.SubElementNode != null)
			{
				foreach (ElementNode ndSub in en.SubElementNode)
				{
					en.AddSubObject(hymepobject, ndSub, ref system);
				}
			}
			return hymepobject;
		}

		private static void AddNext(this HYMEPObject objThis, ElementNode enNext, ref HYDuctSystem system)
		{
			HYMEPObject hymepobject = enNext.CreateObject(ref system);
			if (hymepobject != null)
			{
				objThis.SetNext(hymepobject);
				objThis.Flow += hymepobject.Flow;
				objThis.Flow += objThis.AddFlow;
			}
		}

		public static void AddSubObject(this ElementNode enThis, HYMEPObject objThis, ElementNode ndSub, ref HYDuctSystem system)
		{
			if (ndSub == null)
			{
				return;
			}
			HYMEPObject hymepobject = ndSub.CreateObject(ref system);
			if (hymepobject == null)
			{
				return;
			}
			objThis.Flow += hymepobject.Flow;
			objThis.Flow += objThis.AddFlow;
			if (objThis is HYDuctStraight)
			{
				HYDuctStraight hyductStraight = objThis as HYDuctStraight;
				if (hymepobject is HYDuctTaper)
				{
					HYDuctTaper hyductTaper = hymepobject as HYDuctTaper;
					hyductTaper.Coefficient = ndSub.ConnectorIn.Coefficient;
					hyductTaper.Offset = RevitUtils.GetDistance(ndSub.ConnectorIn, enThis.ConnectorIn);
					hyductStraight.AddTaper(hyductTaper);
					return;
				}
				objThis.SetNext(hymepobject);
				return;
			}
			else
			{
				if (!(objThis is HYFlexDuct))
				{
					if (objThis is HYDuctTee)
					{
						HYDuctTee hyductTee = objThis as HYDuctTee;
						hyductTee.IsConfluence = system.IsConfluence;
						Connector connector = null;
						Connector connector2 = null;
						enThis.GetSideConnector(out connector, out connector2);
						if (RevitUtils.IsLink(connector, ndSub.ConnectorIn))
						{
							hyductTee.SetSideObject(hymepobject);
							hyductTee.SideCofficient = connector.Coefficient;
						}
						if (objThis is HYDuctCross)
						{
							HYDuctCross hyductCross = objThis as HYDuctCross;
							if (RevitUtils.IsLink(connector2, ndSub.ConnectorIn))
							{
								hyductCross.SetSide2Object(hymepobject);
								hyductCross.Side2Cofficient = connector2.Coefficient;
							}
						}
						RevitDataExchange.GetTeeLinkInfo(hyductTee, enThis.ConnectorIn, enThis.ConnectorOut, connector, connector2);
					}
					return;
				}
				HYFlexDuct hyflexDuct = objThis as HYFlexDuct;
				if (hymepobject is HYDuctTaper)
				{
					HYDuctTaper hyductTaper2 = hymepobject as HYDuctTaper;
					hyductTaper2.Coefficient = ndSub.ConnectorIn.Coefficient;
					hyductTaper2.Offset = RevitUtils.GetDistance(ndSub.ConnectorIn, enThis.ConnectorIn);
					hyflexDuct.AddTaper(hyductTaper2);
					return;
				}
				objThis.SetNext(hymepobject);
				return;
			}
		}
	}
}
